const path = require('path');
const fs = require('fs');
const isBasic = (process.env.npm_lifecycle_script || '').includes('--locale=basic')
const pathResolve = (str) => path.resolve(__dirname, '../dist' + str);
const locale = require(pathResolve(isBasic ? '/basic/locale.js' : '/components/locale.js'));
const outPath = isBasic ? '/basic' : '/components';
const localeData = {};
Object.keys(locale).forEach(key => {
    Object.keys(locale[key]).forEach(lang => {
        if (!localeData[lang]) {
            localeData[lang] = {};
        }
        if (!localeData[lang][key]) {
            localeData[lang][key] = {}
        }
        if (locale[key] && locale[key][lang]) {
            Object.assign(localeData[lang][key], locale[key][lang])
        }
    })
})
localeData.en = localeData['en-US'];
delete localeData['en-US'];
Object.keys(localeData).forEach(key => {
    fs.writeFileSync(pathResolve(`${outPath}/${key.toLowerCase()}.json`), JSON.stringify(lowerJSONKey(localeData[key]), undefined, ' '))
});

// 生成表单组件列表, 后端需要
if (!isBasic) {
    const formComponents = [];
    const formPath = path.resolve(__dirname, '../src/core/components/form');
    getPath(formPath).forEach(([dir]) => {
        const components = getPath(dir);
        components.forEach(([path, componentName]) => {
            const name = componentName.toLowerCase()
            if (name == 'synccomponents') {
                const syncComponents = getPath(path);
                syncComponents.forEach(([_, sName]) => {
                    const name = sName.toLowerCase();
                    formComponents.push(name)
                })
            } else {
                formComponents.push(name)
            }
        })
    })
    fs.writeFileSync(pathResolve(`${outPath}/form.json`), JSON.stringify(formComponents, undefined, ' '))
}

// 获取文件夹下的子文件夹
function getPath(dirPath) {
    const arr = [];
    const dirs = fs.readdirSync(dirPath);
    dirs.forEach(child => {
        const childPath = path.resolve(dirPath + '/' + child);
        const state = fs.lstatSync(childPath);
        if (state.isDirectory()) {
            arr.push([childPath, child])
        }
    })
    return arr
};

const componentsPath = './src/core/components';

// 需要validate的表单组件
const formValidateComponents = [
    "EformInput",
    "EformNumber",
    "EformRichText",
    "EformTextArea",
    "EformDatePicker",
    "EformDateRangePicker",
    "EformStaticList",
    "EformDynamicList",
    "GeoLocation",
    "TreeSelect",
    "Transfer",
    "Cascader",
    "Table",
    "EformMemberSelect",
];

const LangBasic = [
    'PermissionConfig', 'Pagination',
    'AuthForm', 'InbizUpload',
    'EditableTable', 'SelectMessageGroup',
    'Tinymce', 'DocSelect',
    'SelectDoc', 'PageSelect',
    'IconPicker', 'BiFilterModal',
    'BelongDirectory', 'EnvironmentSelect',
    'FormSelect', 'EformSelectDoc',
    'DataQuery', 'ClassPicker',
    'TreeAndTable', 'MultilingualInput',
    'LangManage', 'FormManage',
    'WapProcessLog', 'ProcessLog',
    'MemberSelect', 'WapSearchBar',
    'ProcessManage', 'WapMemberSelect',
];

function isFirstLetterUpperCase(str) {
    var regex = /^[A-Z]/;
    return regex.test(str);
};

function getAllFoldersPath(folderPath, foldersPath) {
    const _foldersPath = foldersPath || [];
    const folders = fs.readdirSync(folderPath);
    folders.forEach(folder => {
        const _folderPath = folderPath + '/' + folder;
        const stats = fs.statSync(_folderPath);
        if (stats.isDirectory()) {
            if(folder == 'preview'){
                _foldersPath.push(_folderPath);
            }
            getAllFoldersPath(_folderPath, _foldersPath);
        };
    });
    return _foldersPath;
};

function getAllFilesPath(folderPath, filesPath) {
    const _filesPath = filesPath || [];
    const files = fs.readdirSync(folderPath);
    files.forEach(file => {
        const filePath = folderPath + '/' + file;
        const isFile = fs.statSync(filePath).isFile();
        if (isFile) {
            _filesPath.push(filePath);
        } else {
            getAllFilesPath(filePath, _filesPath);
        };
    });
    return _filesPath;
};

function getLang(componentsPath) {
    let resultObject = {};
    const previewFolderPathes = getAllFoldersPath(componentsPath);
    previewFolderPathes?.forEach(path => {
        let _path = path.slice(0, path.length - 8);
        const component = _path.slice(_path.lastIndexOf('/') + 1);
        let componentBasic = [];
        const allFilesPath = getAllFilesPath(path);
        const basicArray = allFilesPath.map(filePath1 => {
            const data = fs.readFileSync(filePath1, 'utf8');
            const reg = /@inbiz\/basic\/(.+)['"]/g;
            const matchedStrings = data.match(reg);
            return matchedStrings || [];
        });
        const _basicArray = basicArray.filter((item) => item.length != 0);
        componentBasic = Array.from(new Set(_basicArray.flat(2))).map((item) => item.slice(item.lastIndexOf('/') + 1, item.length - 1)).filter((item1) => LangBasic.includes(item1));
        if (isFirstLetterUpperCase(component)) {
            resultObject[component] = {
                "basic": componentBasic,
            };
            if (formValidateComponents.includes(component)) {
                resultObject[component]["common"] = ["validate"];
            };
        };
    })
    const directoryPath = './dist/components';
    const fileName = 'basic.json';
    const filePath = path.join(directoryPath, fileName);
    fs.mkdirSync(directoryPath, {
        recursive: true,
    });
    fs.writeFileSync(filePath, JSON.stringify(resultObject, null, 2).toLocaleLowerCase());
};

if (!isBasic) {
    getLang(componentsPath);
};


function lowerJSONKey(json) {
    if (json instanceof Array) {
      return json
    } else if (json instanceof Object) {
      for (var key in json) {
        var reg = /[A-Z]/;
        if (json[key] instanceof Object || json[key] instanceof Array) {
            if (reg.test(key)) {
                var lowerKey = key.toLowerCase();
                json[lowerKey] = lowerJSONKey(json[key]);
                delete json[key];
            } else {
                json[key] = lowerJSONKey(json[key]);
            }
        } else {
          if (reg.test(key)) {
            var lowerKey = key.toLowerCase();
            json[lowerKey] = json[key];
            delete json[key];
          }
        }
      }
    }
    return json;
}